﻿using Xenta.Entities;

namespace Xenta.Plugins
{
    /// <summary>
    /// Exposes the sales rule handler interface.
    /// </summary>
    /// <remarks>
    /// The result code explanation for the Apply and Commit methods.
    /// Negative result, means that rule cannot be applied(internal error).
    /// Zero result, means that rule cannot be applied(no errors).
    /// Positive result, means that rule is applied sucessfully.
    /// </remarks>
    public interface ISalesRuleHandler : IPlugin
    {
        /// <summary>
        /// Applies the rule to an order.
        /// </summary>
        /// <param name="uow">The unit of work.</param>
        /// <param name="rule">The sales rule.</param>
        /// <param name="order">The order.</param>
        /// <param name="discountAmount">When this method returns, contains the discount amount.</param>
        /// <param name="handlingFee">When this method returns, contains the handling fee.</param>
        /// <param name="shippingPrice">When this method returns, contains the shipping price.</param>
        /// <param name="taxAmount">When this method returns, contains the tax amount.</param>
        /// <param name="total">When this method returns, contains the order total.</param>
        /// <returns>The result code.</returns>
        int Apply(IUnitOfWork uow, 
            SalesRuleEntity rule, 
            OrderEntity order,
            out decimal discountAmount,
            out decimal handlingFee,
            out decimal shippingPrice,
            out decimal taxAmount,
            out decimal total);
        
        /// <summary>
        /// Applies the rule to an order item.
        /// </summary>
        /// <param name="uow">The unit of work.</param>
        /// <param name="rule">The sales rule.</param>
        /// <param name="item">The order item.</param>
        /// <param name="discountAmount">When this method returns, contains the discount amount.</param>
        /// <param name="taxAmount">When this method returns, contains the tax amount.</param>
        /// <param name="total">When this method returns, contains the item total.</param>
        /// <returns>The result code.</returns>
        int Apply(IUnitOfWork uow, 
            SalesRuleEntity rule, 
            OrderItemEntity item,
            out decimal discountAmount,
            out decimal taxAmount,
            out decimal total);

        /// <summary>
        /// Commits the rule usage.
        /// </summary>
        /// <param name="uow">The unit of work.</param>
        /// <param name="history">The sales rule usage history.</param>
        /// <returns>The result code.</returns>
        int Commit(IUnitOfWork uow, SalesRuleHistoryEntity history);

        /// <summary>
        /// Rollbacks the rule usage.
        /// </summary>
        /// <param name="uow">The unit of work.</param>
        /// <param name="history">The sales rule usage history.</param>
        void Rollback(IUnitOfWork uow, SalesRuleHistoryEntity history);
    }
}
